package cn.jbolt.core.api;

import cn.jbolt.core.db.util.JBoltTxKit;
import cn.jbolt.core.model.Application;
import com.jfinal.kit.Ret;

/**
 * JBolt Api应用开发中心 调用返回值
 *
 * @ClassName: ApiMsg
 * @author: JFinal学院-小木 QQ：909854136
 * @date: 2020年3月15日
 */
public class JBoltApiRet extends Ret {
	/**
	 * 返回请求Header中未设置jbolt_appId code:4001
	 */
	public static final JBoltApiRet NO_JBOLT_APPID = JBoltApiRet.fail(4001, "请在Request的Header未设置[jboltappid]");
	/**
	 * 返回请求未设置jbolt_appId code:4001
	 */
	public static final JBoltApiRet NO_JBOLT_APPID_PARAM = JBoltApiRet.fail(4001, "请求未设置[jboltappid],URL or Header");
	/**
	 * appId校验参数异常 code:4002
	 */
	public static final JBoltApiRet APPID_CHECK_ERROR = JBoltApiRet.fail(4002, "appId校验参数异常");

	/**
	 * jwt signature校验失败
	 *
	 * @param application code:4003
	 */
	public static JBoltApiRet SIGNATURE_CHECK_FAILED(Application application) {
		return JBoltApiRet.fail(4003,"jwt signature校验失败", application);
	}

	/**
	 * jwt为空 code：4004
	 */
	public static final JBoltApiRet NO_JBOLT_JWT = JBoltApiRet.fail(4004, "jboltjwt为空");
	/**
	 * jwt 过期 code：4005
	 */
	public static final JBoltApiRet JWT_IS_EXPIRED = JBoltApiRet.fail(4005, "jboltjwt已过期");
	/**
	 * 跨域options请求成功处理返回值
	 */
	public static final Ret OPTIONS = JBoltApiRet.ok().set("OPTIONS", 1);

	/**
	 * 返回请求Application不存在信息 code:4006
	 *
	 * @param appId
	 * @return
	 */
	public static JBoltApiRet APPLICATION_NOT_EXIST(String appId) {
		return JBoltApiRet.fail(4006, String.format("请求的Application不存在:[%s]", appId));
	}

	/**
	 * 返回application未开放信息 code:4007
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet APPLICATION_NOT_ENABLE(Application application) {
		return JBoltApiRet.fail(4007,"请求的Application未开放", application);
	}

	/**
	 * 解析JWT 失败 code:4008
	 *
	 * @param location
	 * @param application
	 * @param msg
	 * @return
	 */
	public static JBoltApiRet JWT_PARSE_FAIL(int location, Application application, String msg) {
		return JBoltApiRet.fail(4008, String.format("解析JWT失败 %s", msg == null ? "" : msg),location, application);
	}

	/**
	 * 解析JWT 失败 code：4008
	 *
	 * @param location
	 * @param application
	 * @return
	 */
	public static JBoltApiRet JWT_PARSE_FAIL(int location, Application application) {
		return JWT_PARSE_FAIL(location, application, null);
	}

	/**
	 * HTTP请求的Method不合法 code:4009
	 */
	public static final JBoltApiRet HTTP_METHOD_ERROR = JBoltApiRet.fail(4009, "HTTP请求的Method不合法");

	/**
	 * 应用尚未关联任何微信小程序 code：4010
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet APP_NOT_LINK_WECHAT_XCX(Application application) {
		return JBoltApiRet.fail(4010,"应用尚未关联任何微信小程序", application);
	}

	/**
	 * 应用尚未关联任何微信小程序 code：4010
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet APP_NOT_LINK_WECHAT_MP(Application application) {
		return JBoltApiRet.fail(4010,"应用尚未关联任何微信公众平台", application);
	}

	/**
	 * 登录失败,code为空 code：4011
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet WX_LOGIN_CODE_NULL(Application application) {
		return JBoltApiRet.fail(4011,"wxLogin-code为空", application);
	}

	/**
	 * 微信小程序状态已禁用 code：4012
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet WECHAT_XCX_DISABLED(Application application) {
		return JBoltApiRet.fail(4012, "微信小程序状态已禁用", application);
	}

	/**
	 * 微信公众平台状态已禁用 code：4012
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet WECHAT_MP_DISABLED(Application application) {
		return JBoltApiRet.fail(4012,"微信公众平台状态已禁用",application);
	}

	/**
	 * 系统内微信小程序配置异常 code：4013
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet WECHAT_XCX_CONFIG_ERROR(Application application) {
		return JBoltApiRet.fail(4013,"系统内微信小程序配置异常", application);
	}

	/**
	 * 系统内微信公众号配置异常 code：4013
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet WECHAT_MP_CONFIG_ERROR(Application application) {
		return JBoltApiRet.fail(4013,"系统内微信公众平台配置异常", application);
	}

	/**
	 * 无法创建微信小程序用户 code：4014
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet WECHAT_XCX_USER_CREATE_FAIL(Application application) {
		return JBoltApiRet.fail(4014,"无法创建微信小程序用户", application);
	}

	/**
	 * 微信小程序用户授权获取信息失败 code：4015
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet WECHAT_XCX_GETUSERINFO_FAIL(Application application) {
		return JBoltApiRet.fail(4015,"微信小程序授权获取用户信息失败", application);
	}

	/**
	 * 微信小程序校验用户授权信息-不完整 code：4016
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet WECHAT_XCX_CHECK_USER_INFO_FAIL(Application application) {
		return JBoltApiRet.fail(4016,"微信小程序校验用户授权信息-不完整", application);
	}

	/**
	 * 微信小程序用户授权解密敏感信息失败 code：4017
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet WECHAT_XCX_DECRYPTUSERINFO_FAIL(Application application) {
		return JBoltApiRet.fail(4017,"微信小程序用户授权解密敏感信息失败", application);
	}

	/**
	 * 微信小程序用户授权后信息更新失败 code：4018
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet WECHAT_XCX_UPDATE_USERINFO_FAIL(Application application, String appendMsg) {
		return JBoltApiRet.fail(4018, String.format("微信小程序用户授权后信息更新失败 \n原因：%s", appendMsg == null ? "未知" : appendMsg),application);
	}

	/**
	 * 微信小程序绑定用户参数异常 code：4019
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet WECHAT_XCX_BINDUSER_PARAM_ERROR(Application application) {
		return JBoltApiRet.fail(4019,"微信小程序绑定用户参数异常", application);
	}

	/**
	 * 微信小程序绑定用户失败 code：4020
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet WECHAT_XCX_BINDUSER_ERROR(Application application) {
		return JBoltApiRet.fail(4020,"微信小程序绑定用户失败", application);
	}

	/**
	 * 微信小程序绑定用户失败 code：4021
	 *
	 * @param application
	 * @param userType
	 * @return
	 */
	public static JBoltApiRet WECHAT_XCX_BINDUSER_NO_USER(Application application, String userType) {
		return JBoltApiRet.fail(4021, String.format("微信小程序绑定用户失败,原因：%s数据不存在！", userType),application);
	}

	/**
	 * 微信小程序绑定用户失败 更新信息失败 code：4022
	 *
	 * @param application
	 * @param userType
	 * @return
	 */
	public static JBoltApiRet WECHAT_XCX_BINDUSER_UPDATE_ERROR(Application application, String userType) {
		return JBoltApiRet.fail(4022, String.format("微信小程序绑定%s失败,原因：更新绑定信息发生异常！", userType),application);
	}

	/**
	 * 微信小程序绑定用户失败 已经存在同类型 code：4023
	 *
	 * @param application
	 * @param userType
	 * @return
	 */
	public static JBoltApiRet WECHAT_XCX_BINDUSER_SAMETYPE_EXIST(Application application, String userType) {
		return JBoltApiRet.fail(4023, String.format("微信小程序绑定%s失败,原因：已经存在同类型下的用户绑定！", userType),application);
	}

	/**
	 * 微信小程序用户手机号授权获取信息失败 code：4024
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet WECHAT_XCX_GETPHONENUMBER_FAIL(Application application) {
		return JBoltApiRet.fail(4024,"微信小程序授权获取用户手机号失败", application);
	}

	/**
	 * 微信小程序用户手机号授权后信息更新失败 code：4025
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet WECHAT_XCX_UPDATE_USER_PHONENUMBER_FAIL(Application application, String appendMsg) {
		return JBoltApiRet.fail(4025, "微信小程序用户手机号授权后信息更新失败 \n原因：%s", appendMsg == null ? "未知" : appendMsg,application);
	}

	/**
	 * 后台接口 尚未登录 调用接口 code：4026
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet NOT_ADMIN_LOGIN(Application application) {
		return JBoltApiRet.fail(4026, "尚未登录", application);
	}

	/**
	 * 后台接口 异端顶替 code：4027
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet TERMINAL_OFFLINE(Application application) {
		return JBoltApiRet.fail(4027,"当前账户已在其它终端登录，本机已下线", application);
	}

	/**
	 * 后台接口 强退下线 code：4028
	 *
	 * @param application
	 * @return
	 */
	public static JBoltApiRet FORCED_OFFLINE(Application application) {
		return JBoltApiRet.fail(4028,"当前账户被平台强退下线，如有问题，请联系平台管理", application);
	}
	/**
	 * refresh jwt为空 code：4029
	 */
	public static final JBoltApiRet NO_JBOLT_REFRESH_JWT = JBoltApiRet.fail(4029, "jboltrefreshjwt为空");
	/**
	 * refresh jwt 过期 code：4030
	 */
	public static final JBoltApiRet REFRESH_JWT_IS_EXPIRED = JBoltApiRet.fail(4030, "jboltrefreshjwt已过期");

	/**
	 * jwt 检测无效 需要前端清空 code：4031
	 */
	public static final JBoltApiRet JWT_API_USER_CHECK_EFFECTIVE_TOKEN_FAILD = JBoltApiRet.fail(4031, "授权登录已失效，请重新登录");

	@Override
	public JBoltApiRet set(Object key, Object value) {
		super.set(key, value);
		return this;
	}

	public static JBoltApiRet success() {
		return new JBoltApiRet(0, null, null);
	}

	public static JBoltApiRet successWithData(Object data) {
		return new JBoltApiRet(0, null, data);
	}

	public static JBoltApiRet success(String msg) {
		return new JBoltApiRet(0, msg, null);
	}

	public static JBoltApiRet success(String msg, Object data) {
		return new JBoltApiRet(0, msg, data);
	}

	public static JBoltApiRet fail(int code, String msg) {
		return new JBoltApiRet(code, msg, null);
	}

	public static JBoltApiRet warn(int code, String msg) {
		return warn(code,msg,null,null);
	}

	public static JBoltApiRet warn(int code, String msg,Application application) {
		return warn(code,msg,null,application);
	}

	public static JBoltApiRet warn(int code, String msg,Object data) {
		return warn(code,msg,data,null);
	}

	public static JBoltApiRet warn(int code, String msg,Object data,Application application) {
		JBoltApiRet ret = new JBoltApiRet(code, msg, data);
		if(application!=null){
			ret.application(application);
		}
		ret._setState("warn");
		return ret;
	}

	public static JBoltApiRet fail(int code, String msg,Application application) {
		return new JBoltApiRet(code, msg, null).application(application);
	}

	public static JBoltApiRet fail(int code, String msg,Application application,int location) {
		return new JBoltApiRet(code, msg, null).location(location).application(application);
	}

	public static JBoltApiRet fail(int code, String msg, Object data) {
		return new JBoltApiRet(code, msg, data);
	}

	public static JBoltApiRet fail(int code, String msg, Object data,Application application) {
		return new JBoltApiRet(code, msg, data).application(application);
	}

	public static JBoltApiRet fail(int code, String msg, Object data,Application application,int location) {
		return new JBoltApiRet(code, msg, data).location(location).application(application);
	}

	/**
	 * 返回API 结果
	 *
	 * @param code 错误码 0是正常 其它是错误
	 * @param msg  API错误信息描述
	 * @param data 返回数据
	 */
	private JBoltApiRet(int code, String msg, Object data) {
		if (code == 0) {
			setOk();
		} else {
			setFail();
			JBoltTxKit.isNeedRollback();
			JBoltTxKit.setErrorMsg(msg);
		}
		set("code", code);
		setIfNotBlank("msg", msg);
		setIfNotNull("data", data);
	}

	private JBoltApiRet location(int location){
		set("location", location);
		return this;
	}

	private JBoltApiRet application(Application application){
		set("app", String.format("%s[%s]",application.getName(),application.getAppId()));
		return this;
	}

	public Integer getLocation(){
		return getInt("location");
	}

	public String getApp(){
		return getStr("app");
	}

	public String getMsg() {
		return getStr("msg");
	}

	public JBoltApiRet setMsg(String msg) {
		setIfNotBlank("msg", msg);
		return this;
	}

	public Integer getCode() {
		return getInt("code");
	}

	public <T> T getData() {
		return getAs("data");
	}

	/**
	 * 调用API 返回失败消息
	 *
	 * @param msg
	 * @return
	 */
	public static JBoltApiRet API_FAIL(Application application, String msg) {
		return API_FAIL(application, msg, null);
	}

	/**
	 * 调用API 返回成功消息
	 *
	 * @param msg
	 * @return
	 */
	public static JBoltApiRet API_SUCCESS(String msg) {
		return API_SUCCESS(msg, null);
	}

	/**
	 * 调用API 返回成功消息
	 *
	 * @param msg
	 * @param data
	 * @return
	 */
	public static JBoltApiRet API_SUCCESS(String msg, Object data) {
		return JBoltApiRet.success(msg, data);
	}

	/**
	 * 调用API 成功并返回携带数据
	 *
	 * @param data
	 * @return
	 */
	public static JBoltApiRet API_SUCCESS_WITH_DATA(Object data) {
		return JBoltApiRet.successWithData(data);
	}

	/**
	 * 调用API 返回成功消息
	 *
	 * @param msg
	 * @return
	 */
	public static final JBoltApiRet API_SUCCESS = JBoltApiRet.success();

	/**
	 * API失败消息 code:4000
	 *
	 * @param location
	 * @param application
	 * @param msg
	 * @return
	 */
	public static JBoltApiRet API_FAIL(int location, Application application, String msg) {
		return API_FAIL(location, application, msg, null);
	}

	/**
	 * Api失败信息 code:4000
	 *
	 * @param location
	 * @param application
	 * @param msg
	 * @return
	 */
	public static JBoltApiRet API_FAIL(int location, Application application, String msg, Object data) {
		if (application == null) {
			return API_FAIL(location, msg, data);
		}
		return JBoltApiRet.fail(4000, msg, data,application,location);
	}

	/**
	 * Api失败信息 无Application code:4000
	 *
	 * @param location
	 * @param msg
	 * @param data
	 * @return
	 */
	public static JBoltApiRet API_FAIL(int location, String msg, Object data) {
		return JBoltApiRet.fail(4000, msg, data);
	}

	/**
	 * Api失败信息 无Application code:4000
	 *
	 * @param msg
	 * @param data
	 * @return
	 */
	public static JBoltApiRet API_FAIL(String msg, Object data) {
		return JBoltApiRet.fail(4000, msg, data);
	}

	/**
	 * Api失败信息 无Application code:4000
	 *
	 * @param msg
	 * @return
	 */
	public static JBoltApiRet API_FAIL(String msg) {
		return JBoltApiRet.fail(4000, msg);
	}

	/**
	 * Api失败信息 code:4000
	 *
	 * @param application
	 * @param msg
	 * @param data
	 * @return
	 */
	public static JBoltApiRet API_FAIL(Application application, String msg, Object data) {
		return API_FAIL(0, application, msg, data);
	}

	/**
	 * 删除属性
	 *
	 * @param keys
	 */
	public void delete(String... keys) {
		if (keys != null && keys.length > 0) {
			for (String key : keys) {
				delete(key);
			}
		}
	}
}
